package com.uitls.utils;

import android.util.Log;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * @author zhouzechao
 * 反射获取
 */
public class InstanceUtil {
    public final static int INVALID_VALUE = -1;

    public static int getIntFileValueFromClass(Class c, String filedName) {
        Field field;
        int fieldValue = 0;
        try {
            field = c.getDeclaredField(filedName);
            field.setAccessible(true);
            fieldValue = field.getInt(c);
        } catch (Exception ex) {
            Log.getStackTraceString(ex);
        }
        return fieldValue;
    }

    public static Object getFieldValue(Object object, String fieldName) {
        Class classType = object.getClass();
        Object fieldValue = null;
        try {
            Field field = classType.getDeclaredField(fieldName);
            field.setAccessible(true);
            fieldValue = field.get(object);
        } catch (NoSuchFieldException ex) {
            Log.getStackTraceString(ex);
        } catch (Exception ex) {
            Log.getStackTraceString(ex);
        }
        return fieldValue;
    }

    /**
     * 反射生成对象
     *
     * @param o
     * @param i
     * @param <T>
     * @return
     */
    public static <T> T newInstance(Object o, int i) {
        try {
            return (T) getSuperClassGenricType(o.getClass(), i).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 反射生成对象
     *
     * @param c
     * @param i
     * @param <T>
     * @return
     */
    public static <T> T newInstance(Class c, int i) {
        try {
            return (T) getSuperClassGenricType(c, i).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 通过名字反射
     *
     * @param className
     * @param <T>
     * @return
     */
    public static <T> T newInstance(String className) {
        try {
            return (T) Class.forName(className).newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 通过反射,获得定义Class时声明的父类的范型参数的类型.
     * 如public BookManager extends GenricManager<Book>
     *
     * @param clazz The class to introspect
     * @return the first generic declaration, or <code>Object.class</code> if cannot be determined
     */
    public static Class getSuperClassGenricType(Class clazz) {
        return getSuperClassGenricType(clazz, 0);
    }

    /**
     * 通过反射,获得定义Class时声明的父类的范型参数的类型.
     * 如public BookManager extends GenricManager<Book>
     */
    private static Class getSuperClassGenricType(Class clazz, int index) throws IndexOutOfBoundsException {

        Type genType = clazz.getGenericSuperclass();

        if (!(genType instanceof ParameterizedType)) {
            return Object.class;
        }

        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();

        if (index >= params.length || index < 0) {
            return Object.class;
        }
        if (!(params[index] instanceof Class)) {
            return Object.class;
        }
        return (Class) params[index];
    }
}
